package ext;

import image.ImageGroup;
import image.ps.PixelShader;
import java.awt.Color;
import math.mat3;
import math.vec2i;
import math.vec3;
import math.vec3i;

public class PSTonemap extends PixelShader
{
    
    private static final mat3 XYZ_FROM_RGB = mat3.asRows(
        new vec3(0.412315, 0.212600, 0.019327), 
        new vec3(0.357600, 0.715200, 0.119200), 
        new vec3(0.180500, 0.07220, 0.950633)
    );
    
    private static final mat3 RGB_FROM_XYZ = mat3.asRows( // just the inverse of above.
        new vec3(3.24156, -0.96920, 0.05562), 
        new vec3(-1.53767, 1.87589, -0.20396), 
        new vec3(-0.49870, 0.04155, 1.05686)
    );
    
    
    public int mTargetI3;
    
    
    public PSTonemap()
    {
        super();
        this.mTargetI3 = -1;
    }
    
    
    public PixelShader copy()
    {
        PSTonemap copy = new PSTonemap();
        copy.mTargetI3 = this.mTargetI3;
        return copy;
    }
    
    
    public void shade(
            ImageGroup aTarget, 
            vec2i aImagePixel, 
            vec2i aImageSize)
    {
        vec3 datum = aTarget.image3(this.mTargetI3).read(aImagePixel);
        vec3i rgb = new vec3i(
            (int)(0.5 + 255.0 * datum.x), 
            (int)(0.5 + 255.0 * datum.y), 
            (int)(0.5 + 255.0 * datum.z)
        );
        float[] hsb = Color.RGBtoHSB(rgb.x, rgb.y, rgb.z, null);
        hsb[2] /= (hsb[2] + 1);
        Color rgbc = Color.getHSBColor(hsb[0], hsb[1], hsb[2]);
        float[] rgbf = rgbc.getComponents(null);
        datum.set(rgbf[0], rgbf[1], rgbf[2]);
    }
    
    
    private vec3 XYZ_from_RGB(vec3 RGB)
    {
        vec3 XYZ = XYZ_FROM_RGB.mul(RGB);
//        XYZ.clamp(0.0, 1.0);
        return XYZ;
    }
    
    private vec3 RGB_from_XYZ(vec3 XYZ)
    {
        vec3 RGB = RGB_FROM_XYZ.mul(XYZ);
        RGB.clamp(0.0, 1.0);
        return RGB;
    }
    
}
